﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CardCharger.lib;
using System.Threading;



namespace CardCharger.forms
{
    

    public delegate void OnFormClosing(object sender,EventArgs arg);

    public partial class ReadWriteParas : Form
    {

        private ErrorListFrom elf = new ErrorListFrom();


        /// <summary>
        /// 窗口关闭事件
        /// </summary>
        public event OnFormClosing onFormClosing;

        //用到的通信接口
        SerialPortSetting sps = null;

        //接收数据包
        List<MeterPacket> mp = new List<MeterPacket>();
        //MeterPacket mp;
        AutoResetEvent are = new System.Threading.AutoResetEvent(false);
        AutoResetEvent oare = new AutoResetEvent(false);
        Mutex threadMutex = new Mutex(false);

        //更新标志
        bool AutoRefresh = false;
        System.Timers.Timer timer = new System.Timers.Timer();
        int StartOrStop = 0; //start 1 stop 2

        public class DataItem{
            public bool comflag;  
            public string name;
            public string Val;

            public DataItem(bool _flag, string _name, string _Val) { comflag = _flag; name = _name; Val = _Val; }
        }

        //数据包
        public PacketView pv = null;


        //数据内容
       DataItem[] lDataItem = new DataItem[]{
            new DataItem(false,"相数","单相"),
            new DataItem(false,"系统状态","空闲"),
            new DataItem(false,"当前A相电压","0V"),
            new DataItem(false,"当前B相电压","0V"),
            new DataItem(false,"当前C相电压","0V"),
            new DataItem(false,"当前A相电流","0A"),
            new DataItem(false,"当前B相电流","0A"),
            new DataItem(false,"当前C相电流","0A"),
            new DataItem(false,"充电电量","0度"),
            new DataItem(false,"充电单价","0元"),
            new DataItem(false,"充电金额","0元"),
            new DataItem(false,"充电时间","0/0/0 0:0:0"),
        };
        //显示的表
       DataTable dt = new DataTable("value");



       public void InitDataTable()
       {
           DataColumn comm = new DataColumn("通信", typeof(bool));
           DataColumn name = new DataColumn("参数", typeof(string));
           DataColumn v = new DataColumn("数值", typeof(string));
           dt.Columns.Add(comm);
           dt.Columns.Add(name);
           dt.Columns.Add(v);

           foreach (DataItem di in lDataItem) {
               dt.Rows.Add(di.comflag,di.name,di.Val);
           }
           this.dgv.DataSource = null;
           this.dgv.DataSource = dt.DefaultView;
       }

       void SetCheckCS(DataGridViewCheckBoxCell c, DataItem di) {
           DataGridViewCellStyle cs = new DataGridViewCellStyle();
           if (di.comflag == false)
           {
               cs.BackColor = Color.Red;
           }
           else
           {

               cs.BackColor = Color.Green;
           }

           c.Style = cs;
           c.Value = di.comflag;
           return;
       }
       void SetValueCS(DataGridViewTextBoxCell c, DataItem di)
       {
           if (di.comflag == false) return;
           DataGridViewCellStyle cs = new DataGridViewCellStyle();
           string old = c.Value as string;
           if (di.Val != old)
           {
               cs.BackColor = Color.Green;
           }
           else
           {
               cs.BackColor = Color.White;
           }
           c.Style = cs;
           return;
       }
       public void RefreshData()
       {

           ///////////////////////////////////////////
           //更改样式
           for (int i = 0; i < lDataItem.Length; i++){
               DataItem di = lDataItem[i];
               DataRow dr = dt.Rows[i];
               SetCheckCS(dgv.Rows[i].Cells[0] as DataGridViewCheckBoxCell, di);
               SetValueCS(dgv.Rows[i].Cells[2] as DataGridViewTextBoxCell, di);
               if ((bool)dr[0] != di.comflag) dr[0] = di.comflag;
               if(di.Val !=null)
                    if (dr[2] as string != di.Val) dr[2] = di.Val;
           }
          // dgv.DataSource = null;
           dgv.DataSource = dt;
           //////////////////////////////////////////
           //刷新
           //for (int i = 0; i < lDataItem.Length; i++)
           //{
           //    DataItem di = lDataItem[i];
           //    SetCheckCS(dgv.Rows[i].Cells[0] as DataGridViewCheckBoxCell, di);
           //    SetValueCS(dgv.Rows[i].Cells[2] as DataGridViewTextBoxCell, di);
           //}
           dgv.CurrentCell = null;
       }

        public ReadWriteParas()
        {
            InitializeComponent();
            dgv.RowHeadersVisible = false;
            InitDataTable();
            this.Click += ReadWriteParas_Click;
            this.groupBox1.Click += groupBox1_Click;
        }

        public ReadWriteParas(SerialPortSetting _sps) : this() { 
            sps = _sps;
            sps.onPacketReceive += sps_onPacketReceive;
            sps.onPacketSend += sps_onPacketSend;
            DoubleBuffered = true;  
        }


        void sps_onPacketSend(object sender, Ulitily.PacketArgs args)
        {
            if (this.InvokeRequired)
            {

                Ulitily.onPacketTransfer pt = new Ulitily.onPacketTransfer(sps_onPacketSend);
                this.Invoke(pt, new object[] { sender, args });
            }
            else
            {
                if (pv != null) pv.PacketSend(this, args);
            }
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            timer.Stop();
            threadMutex.WaitOne();
            int wt = sps.PacketWaitTime();
            if (wt < 500) wt = 500;
            //定时下发数据包 00000007
            mp.Clear();
            MeterPacket smp = new MeterPacket(new Code(0x11));
            smp.meterNumberHex = 0;
            smp.DI07 = 0x07000000;
            smp.len = 4;
            sps.WritePacket(smp);
            if (are.WaitOne(wt,false) == false) {
                Console.WriteLine("07000000 收不到");
                Deal07000000(null);
                //goto Error;
            }

            are.Reset();

            //01000007
            smp = new MeterPacket(new Code(0x11));
            smp.meterNumberHex = 0;
            smp.DI07 = 0x07000002;
            smp.len = 4;
            sps.WritePacket(smp);
            if (are.WaitOne(wt,false) == false) {
                Console.WriteLine("07000002 收不到");
                Deal07000002(null);
                //goto Error;
            }
            RefreshDGV();
            threadMutex.ReleaseMutex();
            timer.Start();
            return;

            Error:
            are.Reset();
            threadMutex.ReleaseMutex();
            return;
        }
        delegate void RefreshThread();
        void RefreshDGV()
        {

            if (dgv.InvokeRequired)
            {
                RefreshThread r = new RefreshThread(RefreshDGV);
                dgv.Invoke(r, null);
            }
            else {
                RefreshData();
            }
        }


        #region 数据包处理　函数
        //启动充电
        void Deal07000001Start(MeterPacket p)
        {
            try {

                if (p.len ==0) MessageBox.Show("启动成功");
            }
            catch { }
        
        }
        void Deal07000001Stop(MeterPacket p)
        {
            try
            {

                if (p.len == 0) MessageBox.Show("停止成功");
            }
            catch { }

        }
        //处理00000007
        void Deal07000000(MeterPacket p){

            DataItem di1 = lDataItem[0];
            DataItem di2 = lDataItem[1];     
            try {
                if (p.len != 6) { Console.WriteLine("状态出错"); return; }
                if (p.DI07 != 0x07000000) { Console.WriteLine("接收的不是07000000，而是:{0:D8}", p.DI07); return; }

                switch (p.dataRaw[4]) { 
                    case 1:
                        di1.Val = "单相";
                        break;
                    case 3:
                        di1.Val = "三相";
                        break;
                    default: throw (new Exception("单三相数据错误"));
                }
                di1.comflag = true;
                int error = (int)(p.dataRaw[5]);
                if (p.dataRaw[5] > 128) { error = 256 - error; error *= -1; }
                switch (p.dataRaw[5]) { 
                
                    case 0:
                        di2.Val = "空闲";
                        break;
                    case 1:
                        di2.Val = "正在充电";
                        break;
                    case 2:
                        di2.Val = "停止充电";
                        break;
                    case 3:
                        di2.Val = "系统错误";
                        break;
                    default:
                        di2.Val = error.ToString();
                        break;
                
                }
                di2.comflag = true;            
            }
            catch {

                di1.comflag = di2.comflag = false;
                di1.Val = di2.Val = null;
            }
        }
        void Deal07000002(MeterPacket p)
        {
            try{
                if (p.len != 28) { Console.WriteLine("实时数据出错"); return; }
                if (p.DI07 != 0x07000002) { Console.WriteLine("接收到的不是07000002，而是:{0:D8}", p.DI07); return; }
                int i = 0;
                for ( i = 2; i < 11; i++) {          
                    UInt16  v =0;
                    if (Ulitily.ShareClass.BytesToUInt16(p.dataRaw, (int)(i*2), ref v, 0) == 1) {
                        string s = string.Format("{0:d}.{1:D2}",v/100,v%100);
                        switch (i) {
                            case 2:
                            case 3:
                            case 4: s += "V";break;
                            case 5:
                            case 6:
                            case 7: s += "A"; break;
                            case 8: s += "度"; break;
                            case 9:
                            case 10: s += "元"; break;
                        }
                        lDataItem[i].comflag = true;
                        lDataItem[i].Val = s;
                    }
                    
                }

                if (i == 11) {
                    string s = string.Format("{5:D2}/{4:D2}/{3:D2} {2:D2}:{1:D2}:{0:D2}", p.dataRaw[22], p.dataRaw[23], p.dataRaw[24]
                        , p.dataRaw[25], p.dataRaw[26], p.dataRaw[27]);
                    lDataItem[11].comflag = true;
                    lDataItem[11].Val = s;
                }


            }catch{
                int i = 0;
                for (i = 2; i < 12; i++) { lDataItem[i].comflag = false; }
            
            }
        }
        //接收到有效数据包
        void sps_onPacketReceive(object sender, lib.Ulitily.PacketArgs args)
        {
            if (this.InvokeRequired)
            {

                Ulitily.onPacketTransfer pt = new Ulitily.onPacketTransfer(sps_onPacketReceive);
                this.Invoke(pt, new object[] { sender, args });
            }
            else
            {

                //数据包处理　
                {
                    if (args.packet.len == 0 || args.packet.len == 1)
                    {
                        switch (StartOrStop) { 
                            case 1:
                                Deal07000001Start(args.packet);
                                break;
                            case 2:
                                Deal07000001Stop(args.packet);
                                break;
                            default:
                                break;
                        }
                        StartOrStop = 0;
                        //确定包
                        oare.Set();
                        Thread.Sleep(0);
                    }
                    else
                    {
                        switch (args.packet.DI07)
                        {
                            case 0x07000000:
                                Deal07000000(args.packet);
                                //下一步
                                are.Set();
                                Thread.Sleep(0);
                                break;
                            case 0x07000002:
                                Deal07000002(args.packet);
                                are.Set();
                                Thread.Sleep(0);
                                break;
                            default:
                                Console.WriteLine("收到未处理的数据包:{0:D8}", args.packet.DI07);
                                break;
                        }
                    }
                }



                if (pv != null) { pv.PacketGet(this, args); }
            }
        }
        #endregion


        void groupBox1_Click(object sender, EventArgs e)
        {
            ReadWriteParas_Click(null, null);
        }
        void ReadWriteParas_Click(object sender, EventArgs e)
        {
            dgv.CurrentCell = null;
        }


        #region 按键操作

        //定时更新
        private void button3_Click(object sender, EventArgs e)
        {
            if (AutoRefresh == true)
            {
                this.button3.Text = "启动更新";
                timer.Stop();
                AutoRefresh = false;
            }
            else {
                try
                {

                    //打开更新
                    int spn = int.Parse(tb_timer.Text, System.Globalization.NumberStyles.Number);
                    if (spn < 1) { spn = 1; tb_timer.Text = 1.ToString() ; }

                    //定时下发数据包
                    timer = new System.Timers.Timer(spn * 1000);
                    timer.Elapsed += timer_Elapsed;
                    timer.AutoReset = true;
                    timer.Enabled = true;
                    AutoRefresh = true;
                    timer.Start();
                }
                catch {

                    MessageBox.Show("无法启动更新");
                    return;
                }

                this.button3.Text = "正在刷新";
            
            }
        }
        //启动
        private void button1_Click(object sender, System.EventArgs e)
        {
            threadMutex.WaitOne();
            oare.Reset();
            int wt = sps.PacketWaitTime();
            if (wt < 500) wt = 500;
            MeterPacket smp;
            smp = new MeterPacket(new Code(0x14));
            smp.meterNumberHex = 0;
            smp.DI07 = 0x07000001;
            smp.dataRaw = new byte[] {0x01,0x00,0x00,0x07,0x01};
            sps.WritePacket(smp);
            StartOrStop = 1;
            if (oare.WaitOne(wt, false) == false)
            {
                Console.WriteLine("启动，收不到返回");
            }
            threadMutex.ReleaseMutex();
        }
        //停止
        private void button2_Click(object sender, System.EventArgs e)
        {
            threadMutex.WaitOne();
            oare.Reset();
            int wt = sps.PacketWaitTime();
            if (wt < 500) wt = 500;
            MeterPacket smp;
            smp = new MeterPacket(new Code(0x14));
            smp.meterNumberHex = 0;
            smp.DI07 = 0x07000001;
            smp.dataRaw = new byte[] { 0x01, 0x00, 0x00, 0x07, 0x00 };
            sps.WritePacket(smp);
            StartOrStop = 2;
            if (oare.WaitOne(wt, false) == false) {
                Console.WriteLine("停止，收不到返回");
            }
            threadMutex.ReleaseMutex();
        }


        //错误码
        private void button_EC_Click(object sender, EventArgs e)
                {
                    if (elf.Visible == true) {elf.Hide(); }
                    else { elf.Show(); }
                }


        #endregion

        
    }
}
